package cn.handong.tool.沪房;

import org.junit.After;
import org.junit.Test;

import java.text.DecimalFormat;

public class 等额本息计算器 {
    /**
     * 查看贷款月供详情
     */
    @Test
    public void getDetails(){
//        for (int i = 1; i <= 360; i++) {
//            getMonthlySupplyDetails(360,2170000,0.0465,i);
//        }

        getMonthlySupply(120,1935912.78,0.0465);
    }

    /**
     * 通用计算月供详情
     * @param loanMonths 还要还几次月供
     * @param loadAmount 此时剩余贷款本金总额
     * @param yearRate 贷款利率
     * @return
     */
    public void getMonthlySupply(int loanMonths, double loadAmount, double yearRate){
        double totalPrincipal = 0; // 还了多少本金
        double totalInterest = 0;  // 还了多少利息
        double monthRate = yearRate / 12; //月利率
        //月供原始数据
        double total = getResult((loadAmount * monthRate * Math.pow(1 + monthRate, loanMonths)) / (Math.pow(1 + monthRate, loanMonths) - 1),0);
        for (int monthNum = 1; monthNum <= loanMonths; monthNum++) {
            //本金
            double principal = getResult(loadAmount*monthRate*Math.pow(1+monthRate,monthNum-1)/(Math.pow(1+monthRate,loanMonths)-1),0);
            //利息
            double interest = getResult(total - principal,0);
            System.out.print("应还本金："+principal);
            System.out.print(" 应还利息："+interest);
            System.out.print(" 应还总额："+total);
            totalPrincipal += principal;
            totalInterest += interest;
            System.out.print(" 共还本金："+getResult(totalPrincipal,0));
            System.out.print(" 共还利息："+getResult(totalInterest,0));
            System.out.println(" 共还总额："+getResult(totalInterest,totalPrincipal));
        }
    }

    @Test
    public void calculateMoney(){
        int yearNum = 30;
        System.out.println("等额本息");
        for (int i = 0; i < yearNum; i++) {
            System.out.print((i+1) + " 年后一次性还完 ");
            double v1 = getLoadData(360, 600000, 0.031, i+1);
            double v2 = getLoadData(360, 2170000, 0.0465, i+1);
            System.out.print(" 公积金利息 "+ v1);
            System.out.print(" 商贷利息 " + v2);
            System.out.println(" 利息总额 " + getResult(v1,v2));
        }

    }

    /**
     * 等额本息
     *
     * 等额本息每月偿还固定金额
     *
     * [贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1]
     * 等额本息计算公式： ［贷款本金 × 月利率 × （ 1 ＋月利率）＾还款月数］ ÷ ［（ 1 ＋月利率）＾还款月数－ 1 ］
     *
     * 等额本金计算公式：每月还款金额 = （贷款本金 / 还款月数） + （本金 — 已归还本金累计额） × 每月利率
     */

    /**
     * 计算等额本息月供
     * @param loanMonths 贷款总月数（360）
     * @param loadAmount 贷款总额
     * @param yearRate 贷款利率
     * @return
     */
    public double getLoadData(int loanMonths, double loadAmount, double yearRate, int yearNum){
        double totalInterest = 0;
        double monthRate = yearRate / 12; //月利率
        DecimalFormat format = new DecimalFormat("#.00");
        //月供原始数据
        double v = (loadAmount * monthRate * Math.pow(1 + monthRate, loanMonths)) / (Math.pow(1 + monthRate, loanMonths) - 1);
        String str_v = format.format(v);
        double v_b = Double.parseDouble(str_v);
        //各期本金
        for (int i = 0; i < (yearNum * 12 + 1); i++) {
            //本金
            double bj = loadAmount*(monthRate)*Math.pow(1+monthRate,i)/(Math.pow(1+monthRate,loanMonths)-1);
            String bjStr = format.format(bj);
            double b_j = Double.parseDouble(bjStr);
            //利息
            double lx = v_b - b_j;
            String lxStr = format.format(lx);
            double l_x = Double.parseDouble(lxStr);
            totalInterest += l_x;
        }
        return Double.parseDouble(format.format(totalInterest));
    }


    /**
     * 计算月供详情
     * @param loanMonths 贷款总月数（360）
     * @param loadAmount 贷款总额
     * @param yearRate 贷款利率
     * @return
     */
    public void getMonthlySupplyDetails(int loanMonths, double loadAmount, double yearRate, int monthNum){
        double monthRate = yearRate / 12; //月利率
        //月供原始数据
        double total = getResult((loadAmount * monthRate * Math.pow(1 + monthRate, loanMonths)) / (Math.pow(1 + monthRate, loanMonths) - 1),0);
        //本金
        double principal = getResult(loadAmount*monthRate*Math.pow(1+monthRate,monthNum-1)/(Math.pow(1+monthRate,loanMonths)-1),0);
        //利息
        double interest = getResult(total - principal,0);
        System.out.print("应还本金："+principal);
        System.out.print("应还利息："+interest);
        System.out.println("应还总额："+total);
    }

    public Double getResult(double v1, double v2){
        double totalV = v1 + v2;
        DecimalFormat format = new DecimalFormat("#.00");
        return Double.parseDouble(format.format(totalV));
    }


    /**
     * 每月还款金额=
     * [贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1],
     * 其中“^还款月数”代表还款月数的次方，比如还款月数为12个月，就代表某个数的12次方，
     * 是一种数学的运算方式。
     */
    @Test
    public void justTest(){
        Integer principal = 2170000;
        Double yearRate = 0.0465;
        Double monthRate = yearRate / 12;
        Integer monthNum = 360;
        Double monthRepayment = (principal * monthRate * Math.pow(1 + monthRate, monthNum)) / (Math.pow(1 + monthRate, monthNum) - 1);
        System.out.println();
    }
}
